////////////////////////////////////////////////////////////////////////////////
//
//	This file is part of Woozox, see <http://code.google.com/p/woozox/>.
//
//	Copyright 2008-2009 Florian David
//
//	Woozoo is free software: you can redistribute it and/or modify
//	it under the terms of the GNU Lesser General Public License as 
//	published by the Free Software Foundation, either version 3 of 
//	the License, or (at your option) any later version.
//
//	Woozoo is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public 
//	License along with Woozoo. If not, see <http://www.gnu.org/licenses/>.
//
////////////////////////////////////////////////////////////////////////////////
package org.woozoo.xhtml.core.base.selector
{
	import org.woozoo.xhtml.core.base.*;
	
	/**
	 * @private
	 * */
	internal class AbstractSelectorOperator implements ISelectorOperator
	{
		private var __elements : Array;
		private var __str : String;
		private var __document : Document;
		private var __debugFunction : Function;
		private var __elementsLength : int;
		private var __lookForChildren : Boolean = false;
		private var __foundSelectorNum : int;
		
		public function init(str : String, elements : Array, document : Document, foundSelectorNum : int) : void {		
			__str = str;
			__elements = elements;
			__document = document;
			__foundSelectorNum = foundSelectorNum;
			if (__str.charAt(0) == " ") {
				__lookForChildren = true;
				__str = __str.slice(1);
			}
			if (__foundSelectorNum == 1) {
				__lookForChildren = true;
				__elements.push(document);
			}
			__elementsLength = elements.length;
		}
		
		protected function _prepareString(str : String) : String {
			return str;
		}
		
		public function operate() : Array {
			__str = _prepareString(__str);
			
			var res : Array;
			if (__lookForChildren) {
				res = _operateChildrenElements(__foundSelectorNum == 1);
			} else {
				res = _operateElements();
			}
			res = __getUnique(res);
			return res;
		}
		
		protected function _operateChildrenElements(checkElements : Boolean) : Array {
			throw new Error('AbstractSelectorOperator::_operateChildrenElements is an abstract method');
		}
		
		protected function _operateElements() : Array {
			throw new Error('AbstractSelectorOperator::_operateElements is an abstract method');
		}
		
		public function getElementAt(index : int) : Element {
			return __elements[index] as Element;
		}
		
		private function __getUnique(list : Array) : Array {
			var res : Array = [];
			for each (var e : Element in list) {
				var b:Boolean = false;
				for each (var ne : Element in res)  {
					if (ne == e)  {
						b = true;
					}
				}
				if(!b) { 
					res.push(e);
				}
			}
			return res;
		}
		
		public function get debugFunction() : Function {
			return __debugFunction;
		}
		public function set debugFunction(value : Function) : void {
			__debugFunction = value;
		}
		
		public function get str() : String {
			return __str;
		}
		public function get elements() : Array {
			return __elements;
		}
		public function get elementsLength() : int {
			return __elementsLength;
		}
		public function get document() : Document {
			return __document;
		}
	}
}